package com.it.day2;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * ClassName: UserDefineClassLoader
 * Description: 自定义类加载器
 *
 * @Author: csx
 * @Create: 2025/4/25 - 18:09
 * @version: v1.0
 */
public class UserDefineClassLoader extends ClassLoader {
    private String rootPath;

    public UserDefineClassLoader(String rootPath) {
        this.rootPath = rootPath;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        //转换为以文件路径表示的文件
        String filePath = classToFilePath(name);

        //获取知道路径的class文件对于的二进制流数据
        byte[] data = getBytesFromPath(filePath);

        //自定义ClassLoader 内部调用defineClass()
        return defineClass(name,data,0,data.length);
    }

    private byte[] getBytesFromPath(String filePath) {
        FileInputStream fis = null;
        ByteArrayOutputStream baos = null;
        try {
            fis = new FileInputStream(filePath);

            baos = new ByteArrayOutputStream();

            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) != -1){
                baos.write(buffer, 0, len);
            }

            return baos.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (baos != null)
                    baos.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            try {
                if (fis != null)
                    fis.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private String classToFilePath(String name) {
        return rootPath + "\\" + name.replace(".", "\\") + ".class";
    }

    public static void main(String[] args) {    //加载User.class
        try {
            UserDefineClassLoader loader1 = new UserDefineClassLoader("E:\\code\\JVM\\src\\main\\java");
            Class class1 = loader1.findClass("com.it.day2.User");
            System.out.println(class1);

            UserDefineClassLoader loader2 = new UserDefineClassLoader("E:\\code\\JVM\\src\\main\\java");
            Class class2 = loader2.findClass("com.it.day2.User");
            //这里就能证明，不同的类加载器，加载的类也是不同的，可以做到一个环境隔离的状态
            System.out.println(class1 == class2);   //false

            System.out.println(class1.getClassLoader());
            System.out.println(class1.getClassLoader().getParent());

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } finally {
        }
    }

}
